// scalaxx - Scala XML eXtensions
// (c) 2009-2010, Normen Müller, normen.mueller@gmail.com
// $Id: E.scala 84 2010-09-26 16:02:32Z normen.mueller $
package scalaxx.diff

import java.io.File

import scala.xml.{Node, Text, MetaData}

import scaup.Views._
import scaup.eq.{EquivalenceSpecification, Alternatives}
import scaup.parsing.eq.EquivalenceSpecificationParser

/** XML base equivalence system.
 * 
 *  @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 *  @version 0.0.5
 */
class BaseEquivalenceSystem extends scaup.eq.EquivalenceSystem[MetaData, Node] {

  val alternatives: Map[String, Alternatives] = Map()

  def ordered(l: String): Boolean = true

  def nameOf[S <: scala.xml.Node](l: S) = l match {
    case l: Text => "<TEXT>"
    case _       => l.label
  }

  def annotationsOf[S <: scala.xml.Node](l: S) = l.attributes

  def constituentsOf[S <: scala.xml.Node](l: S) = l.child.asInstanceOf[Seq[S]]  
}

/** Companion to <code>EquivalenceSystem</code> class.
 * 
 *  @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 *  @version 0.0.5
 */
object EquivalenceSystem {

  def parse(spec: File): EquivalenceSystem =
    if(spec == null)
      error("Equivalence specification may not be null.")
    else if(! (spec exists))
      error("Equivalence specification does not exist.")
    else parse(spec.content)

  def parse(spec: String): EquivalenceSystem =
    if(spec == null)
      error("Equivalence specification may not be null.")
    else new EquivalenceSystem(EquivalenceSpecificationParser.parse(spec))  
}

/** An XML equivalence system with respect to the parametrized equivalence specification.
 * 
 *  @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 *  @version 0.0.5
 */
class EquivalenceSystem(spec: EquivalenceSpecification) extends BaseEquivalenceSystem {
  if(spec == null)
    error("Equivalence specification may not be null.")

  override val alternatives: Map[String, Alternatives] = spec.alternatives

  override def ordered(l: String): Boolean = !(spec.unordered contains l)

  override def toString = spec.toString
}
